home *** CD-ROM | disk | FTP | other *** search
/ Aminet 43 / Aminet 43 (2001)(GTI - Schatztruhe)[!][Jun 2001].iso / Aminet / game / misc / WormWars.lha / WormWars / Source / fe.c < prev    next >
C/C++ Source or Header  |  2001-04-21  |  34KB  |  927 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include "diff.h"
  4. #include "same.h"
  5. #include "amiga.h"
  6.  
  7. #include <intuition/intuition.h> // for struct Window, etc.
  8. #include <libraries/gadtools.h>  // for GT_VisualInfo, etc.
  9.  
  10. #include <stdlib.h>              // for EXIT_SUCCESS, etc.
  11.  
  12. MODULE UWORD chip CustomPointer[] =
  13. {       0x0000, 0x0000,         /* reserved */
  14.  
  15.         0xF000, 0xF800,         /* 1st row 1st plane, 1st row 2nd plane */
  16.         0xF000, 0x8800,         /* 2nd row 1st plane, 2nd row 2nd plane */
  17.         0xF000, 0x8800,         /* 3rd row 1st plane, 3rd row 2nd plane */
  18.         0xF000, 0x8800,         /* 4th row 1st plane, 4th row 2nd plane */
  19.         0xF000, 0x8800,         /* 5th row 1st plane, 5th row 2nd plane */
  20.         0x8000, 0xF800,         /* 6th row 1st plane, 6th row 2nd plane */
  21.  
  22.         0x0000, 0x0000          /* reserved */
  23. };
  24.  
  25. #define ALTJUMP         5
  26. #define JOYDELAY        50000                         /* 1,000,000 / JOYDELAY = movement in squares per second */
  27. #define UNDERLINEOFFSET (58 + STARTYPIXEL)
  28.  
  29. /* pseudo-gadgets */
  30. #define GADGETX         (-3) // negatives must be within brackets
  31. #define EMPTYGADGET    ((FIELDY / 2) -  9)
  32. #define SILVERGADGET   ((FIELDY / 2) -  6)
  33. #define GOLDGADGET     ((FIELDY / 2) -  3)
  34. #define DYNAMITEGADGET  (FIELDY / 2)
  35. #define WOODGADGET     ((FIELDY / 2) +  3)
  36. #define STONEGADGET    ((FIELDY / 2) +  6)
  37. #define METALGADGET    ((FIELDY / 2) +  9)
  38.  
  39. MODULE void setpointer(UBYTE brush);
  40. MODULE void dot(void);
  41. MODULE void undot(void);
  42. MODULE void stamp(UBYTE square);
  43. MODULE void fillfield(UBYTE which);
  44. MODULE void underline(UBYTE square);
  45. MODULE SWORD xpixeltosquare(SWORD x);
  46. MODULE SWORD ypixeltosquare(SWORD y);
  47.  
  48. IMPORT struct Window*        MainWindowPtr;
  49. IMPORT struct Menu*          MenuPtr;
  50. IMPORT struct VisualInfo*    VisualInfoPtr;
  51. IMPORT struct MsgPort*       JoyPortPtr;
  52. IMPORT struct timerequest*   TimerRqPtr;
  53. IMPORT struct InputEvent     GameEvent;
  54. IMPORT struct Screen*        ScreenPtr;
  55.  
  56. IMPORT struct TeleportStruct teleport[MAXLEVELS + 1][4];
  57.  
  58. IMPORT ABOOL               clearthem,
  59.                            icons,
  60.                            joy,
  61.                            modified;
  62. IMPORT SBYTE               a,
  63.                            board[MAXLEVELS + 1][FIELDX + 1][FIELDY + 1],
  64.                            startx[MAXLEVELS + 1],
  65.                            starty[MAXLEVELS + 1],
  66.                            fex = FIELDX / 2,
  67.                            fey = FIELDY / 2,
  68.                            level, levels;
  69.  
  70. MODULE ABOOL               sticky = FALSE;
  71. MODULE UBYTE               brush  = STONE;
  72.  
  73. AGLOBAL void fieldedit(void)
  74. {   AUTO    ABOOL                leftdown  = FALSE,
  75.                                  rightdown = FALSE,
  76.                                  timer     = FALSE;
  77.     AUTO    SBYTE                deltax    = 0, deltay = 0,
  78.                                  mergelevels, pointerx, pointery, which,
  79.                                  x, y;
  80.     AUTO    UWORD                code, qual;
  81.     AUTO    ULONG                class, i;
  82.     AUTO    struct IntuiMessage* MsgPtr;
  83.     AUTO    struct MenuItem*     ItemPtr;
  84.     PERSIST ABOOL                clipboarded = FALSE;
  85.     PERSIST UBYTE                clipboard[FIELDX + 1][FIELDY + 1];
  86.     AUTO    UBYTE                IOBuffer[HISCORESIZE];
  87.  
  88.     say("Field Editor", WHITE);
  89.     setpointer(brush);
  90.     if (level > levels)
  91.         level = levels;
  92.     OnMenu(MainWindowPtr, FULLMENUNUM(MN_EDIT, NOITEM, NOSUB));
  93.     if (!clipboarded)
  94.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_EDIT, IN_PASTE, NOSUB));
  95.  
  96.     /* draw pseudo-gadgets */
  97.     
  98.     clearscreen();
  99.     for (which = 0; which <= 6; which++)
  100.         DrawBevelBox(MainWindowPtr->RPort, STARTXPIXEL - 5 - (SQUAREX * 3), UNDERLINEOFFSET + (which * SQUAREY * 3), SQUAREX + 9, SQUAREY + 4, GT_VisualInfo, VisualInfoPtr);
  101.     SetAPen(MainWindowPtr->RPort, WHITE);
  102.     Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + (   EMPTYGADGET * SQUAREY));
  103.     Text(MainWindowPtr->RPort, "F1:", 3);
  104.     Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + (  SILVERGADGET * SQUAREY));
  105.     Text(MainWindowPtr->RPort, "F2:", 3);
  106.     Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + (    GOLDGADGET * SQUAREY));
  107.     Text(MainWindowPtr->RPort, "F3:", 3);
  108.     Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + (DYNAMITEGADGET * SQUAREY));
  109.     Text(MainWindowPtr->RPort, "F4:", 3);
  110.     Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + (    WOODGADGET * SQUAREY));
  111.     Text(MainWindowPtr->RPort, "F5:", 3);
  112.     Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + (   STONEGADGET * SQUAREY));
  113.     Text(MainWindowPtr->RPort, "F6:", 3);
  114.     Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + (   METALGADGET * SQUAREY));
  115.     Text(MainWindowPtr->RPort, "F7:", 3);
  116.  
  117.     draw(GADGETX,    EMPTYGADGET,    EMPTY);
  118.     draw(GADGETX,   SILVERGADGET,   SILVER);
  119.     draw(GADGETX,     GOLDGADGET,     GOLD);
  120.     draw(GADGETX, DYNAMITEGADGET, DYNAMITE);
  121.     draw(GADGETX,     WOODGADGET,     WOOD);
  122.     draw(GADGETX,    STONEGADGET,    STONE);
  123.     draw(GADGETX,    METALGADGET,    METAL);
  124.  
  125.     SetAPen(MainWindowPtr->RPort, BLACK);
  126.     RectFill
  127.     (   MainWindowPtr->RPort,
  128.         STARTXPIXEL - SQUAREX - 1,
  129.         UNDERLINEOFFSET - 1,
  130.         STARTXPIXEL - SQUAREX + 3,
  131.         UNDERLINEOFFSET + 4 + (SQUAREY * 28)
  132.     );
  133.     underline(brush);
  134.     
  135.     turborender();
  136.     saylevel(WHITE);
  137.     clearkybd();
  138.  
  139.     fex = startx[level];
  140.     fey = starty[level];
  141.     dot();
  142.  
  143.     while (a == FIELDEDIT)
  144.     {   while (MsgPtr = (struct IntuiMessage *) GetMsg(MainWindowPtr->UserPort))
  145.         {   class = MsgPtr->Class;
  146.             code  = MsgPtr->Code;
  147.             qual  = MsgPtr->Qualifier;
  148.             if (class == IDCMP_MENUVERIFY && MsgPtr->MouseX >= STARTXPIXEL && MsgPtr->MouseX <= ENDXPIXEL && MsgPtr->MouseY >= STARTYPIXEL && MsgPtr->MouseY <= ENDYPIXEL)
  149.             {   MsgPtr->Code = MENUCANCEL;
  150.                 rightdown = TRUE;
  151.             }
  152.             ReplyMsg((struct Message *) MsgPtr);
  153.  
  154.             switch (class)
  155.             {
  156.             case IDCMP_MENUPICK:
  157.                 while (code != MENUNULL)
  158.                 {   ItemPtr = ItemAddress(MenuPtr, code);
  159.                     switch (MENUNUM(code))
  160.                     {
  161.                     case MN_PROJECT:
  162.                         switch (ITEMNUM(code))
  163.                         {
  164.                         case IN_NEW:
  165.                             effect(FXFILENEW);
  166.                             newfields();
  167.                             say("New done.", WHITE);
  168.                         break;
  169.                         case IN_OPEN:
  170.                             effect(FXFILEOPEN);
  171.                             fileopen(FALSE);
  172.                         break;
  173.                         case IN_REVERT:
  174.                             fileopen(TRUE);
  175.                         break;
  176.                         case IN_SAVE:
  177.                             effect(FXFILESAVE);
  178.                             if (modified)
  179.                             {   clearhiscores();
  180.                                 modified = FALSE;
  181.                             }
  182.                             filesaveas(FALSE);
  183.                             turborender();
  184.                         break;
  185.                         case IN_SAVEAS:
  186.                             effect(FXFILESAVEAS);
  187.                             if (modified)
  188.                             {   clearhiscores();
  189.                                 modified = FALSE;
  190.                             }
  191.                             filesaveas(TRUE);
  192.                             turborender();
  193.                         break;
  194.                         case IN_PROJECTDELETE:
  195.                             effect(FXEDITDELETE);
  196.                             filedelete();
  197.                         break;
  198.                         case IN_QUIT:
  199.                             if (verify())
  200.                                 cleanexit(EXIT_SUCCESS);
  201.                         break;
  202.                         default:
  203.                         break;
  204.                         }
  205.                     break;
  206.                     case MN_EDIT:
  207.                         switch (ITEMNUM(code))
  208.                         {
  209.                         case IN_CUT:
  210.                             effect(FXEDITCUT);
  211.                             for (x = 0; x <= FIELDX; x++)
  212.                                 for (y = 0; y <= FIELDY; y++)
  213.                                     clipboard[x][y] = board[level][x][y];
  214.                             leveldelete();
  215.                             clipboarded = TRUE;
  216.                             modified = TRUE;
  217.                             OnMenu(MainWindowPtr, FULLMENUNUM(MN_EDIT, IN_PASTE, NOSUB));
  218.                         break;
  219.                         case IN_COPY:
  220.                             effect(FXEDITCOPY);
  221.                             for (x = 0; x <= FIELDX; x++)
  222.                                 for (y = 0; y <= FIELDY; y++)
  223.                                     clipboard[x][y] = board[level][x][y];
  224.                             clipboarded = TRUE;
  225.                             OnMenu(MainWindowPtr, FULLMENUNUM(MN_EDIT, IN_PASTE, NOSUB));
  226.                         break;
  227.                         case IN_PASTE:
  228.                             effect(FXEDITPASTE);
  229.                             for (x = 0; x <= FIELDX; x++)
  230.                                 for (y = 0; y <= FIELDY; y++)
  231.                                     board[level][x][y] = clipboard[x][y];
  232.                             turborender();
  233.                             modified = TRUE;
  234.                         break;
  235.                         case IN_ERASE:
  236.                             levelerase();
  237.                         break;
  238.                         case IN_INSERT:
  239.                             levelinsert();
  240.                         break;
  241.                         case IN_EDITDELETE:
  242.                             effect(FXEDITDELETE);
  243.                             leveldelete();
  244.                         break;
  245.                         case IN_APPEND:
  246.                             levelappend();
  247.                         break;
  248.                         default:
  249.                         break;
  250.                         }
  251.                     break;
  252.                     case MN_SETTINGS:
  253.                         switch(ITEMNUM(code))
  254.                         {
  255.                         case IN_CREATEICONS:
  256.                             if (ItemPtr->Flags & CHECKED)
  257.                                 icons = TRUE;
  258.                             else icons = FALSE;
  259.                         break;
  260.                         default:
  261.                         break;
  262.                         }
  263.                     break;
  264.                     case MN_HELP:
  265.                         switch(ITEMNUM(code))
  266.                         {
  267.                         case IN_CREATURES:
  268.                             help(ORB);
  269.                         break;
  270.                         case IN_OBJECTS:
  271.                             help(AFFIXER);
  272.                         break;
  273.                         case IN_MANUAL:
  274.                             helpmanual();
  275.                         break;
  276.                         case IN_ABOUT:
  277.                             helpabout();
  278.                         break;
  279.                         default:
  280.                         break;
  281.                         }
  282.                     break;
  283.                     default:
  284.                     break;
  285.                     } // hctiws
  286.                     code = ItemPtr->NextSelect;
  287.                 } // elihw
  288.             break;
  289.             case IDCMP_RAWKEY:
  290.                 if (!(qual & IEQUALIFIER_REPEAT))
  291.                 {   effect(FXCLICK);
  292.                 }
  293.                 switch(code)
  294.                 {
  295.                 case DELETE:
  296.                     if (!(qual & IEQUALIFIER_REPEAT))
  297.                     {   if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  298.                             level = 1;
  299.                         elif (--level < 0)
  300.                             level = levels;
  301.                         saylevel(WHITE);
  302.                         turborender();
  303.                     }
  304.                 break;
  305.                 case HELP:
  306.                     if (!(qual & IEQUALIFIER_REPEAT))
  307.                     {   if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  308.                             level = levels;
  309.                         elif (++level > levels)
  310.                             level = 0;
  311.                         saylevel(WHITE);
  312.                         turborender();
  313.                     }
  314.                 break;
  315.                 case Z:
  316.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  317.                     {   /* The undocumented merge function. You will
  318.                         notice that there is absolutely no error checking.
  319.                         This is because you shouldn't really be using this
  320.                         function, unless you know what you are doing. */
  321.  
  322.     say("Merging...", WHITE);
  323.     ZOpen("RAM:Merge.fset", FALSE);
  324.     ZRead(IOBuffer, 10);
  325.     mergelevels = IOBuffer[9];
  326.     for (i = 0; i <= HISCORES; i++)
  327.     {   ZRead(IOBuffer, HISCORESIZE);
  328.     }
  329.     ZRead(IOBuffer, 8);
  330.     ZRead((char *) &board[0][0][0], LEVELSIZE);
  331.  
  332.     for (i = levels + 1; i <= levels + mergelevels; i++)
  333.     {   ZRead(IOBuffer, 8);
  334.         startx[i]            = IOBuffer[0];
  335.         starty[i]            = IOBuffer[1];
  336.         teleport[i][0].alive = IOBuffer[2];
  337.         teleport[i][0].x     = IOBuffer[3];
  338.         teleport[i][0].y     = IOBuffer[4];
  339.         teleport[i][1].alive = IOBuffer[5];
  340.         teleport[i][1].x     = IOBuffer[6];
  341.         teleport[i][1].y     = IOBuffer[7];
  342.         ZRead((char *) &board[i][0][0], LEVELSIZE);
  343.     }
  344.     ZClose();
  345.     levels += mergelevels;
  346.     modified = clearthem = TRUE;
  347.     say("Merge done.", WHITE);
  348.  
  349.                     }
  350.                 break;
  351.                 case M:
  352.                     if (!(qual & IEQUALIFIER_REPEAT))
  353.                         toggle(M);
  354.                 break;
  355.                 case F:
  356.                     if (!(qual & IEQUALIFIER_REPEAT))
  357.                         toggle(F);
  358.                 break;
  359.                 case ESCAPE:
  360.                     if (!(qual & IEQUALIFIER_REPEAT))
  361.                     {   if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  362.                         {   if (verify())
  363.                             {   cleanexit(EXIT_SUCCESS);
  364.                         }   }
  365.                         else
  366.                         {   a = GAMEOVER;
  367.                     }   }
  368.                 break;
  369.                 case SPACEBAR:
  370.                 case RETURN:
  371.                 case ENTER:
  372.                     if (!(qual & IEQUALIFIER_REPEAT))
  373.                         a = GAMEOVER;
  374.                 break;
  375.                 case NUMERICOPEN:
  376.                     setpointer(NORMAL);
  377.                     underline(255);
  378.  
  379.                     brush--;
  380.                     if (brush <= 0 || brush > LASTOBJECT) // note sign issues
  381.                     {   brush = LASTOBJECT;
  382.                     }   stamp(brush);
  383.                 break;
  384.                 case NUMERICCLOSE:
  385.                     setpointer(NORMAL);
  386.                     underline(255);
  387.  
  388.                     brush++;
  389.                     if (brush > LASTOBJECT)
  390.                     {   brush = 0;
  391.                         stamp(brush);
  392.                     }
  393.                 break;
  394.                 case C:
  395.                     effect(FXCENTRE); /* interesting */
  396.                     undot();
  397.                     fex = FIELDX / 2;
  398.                     fey = FIELDY / 2;
  399.                     dot();
  400.                 break;
  401.                 case S:
  402.                     stamp(START);
  403.                 break;
  404.                 case KEY_T:
  405.                     stamp(TELEPORT);
  406.                 break;
  407.                 case O:
  408.                     stamp(OCTOPUS);
  409.                 break;
  410.                 case ALPHAONE:
  411.                     stamp(EMPTY);
  412.                 break;
  413.                 case ALPHATWO:
  414.                     stamp(SILVER);
  415.                 break;
  416.                 case ALPHATHREE:
  417.                     stamp(GOLD);
  418.                 break;
  419.                 case ALPHAFOUR:
  420.                     stamp(DYNAMITE);
  421.                 break;
  422.                 case ALPHAFIVE:
  423.                     stamp(WOOD);
  424.                 break;
  425.                 case ALPHASIX:
  426.                     stamp(STONE);
  427.                 break;
  428.                 case ALPHASEVEN:
  429.                     stamp(METAL);
  430.                 break;
  431.                 case F1:
  432.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  433.                     {   fillfield(EMPTY);
  434.                     } else setbrush(EMPTY);
  435.                 break;
  436.                 case F2:
  437.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  438.                     {   fillfield(SILVER);
  439.                     } else setbrush(SILVER);
  440.                 break;
  441.                 case F3:
  442.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  443.                     {   fillfield(GOLD);
  444.                     } else setbrush(GOLD);
  445.                 break;
  446.                 case F4:
  447.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  448.                     {   fillfield(DYNAMITE);
  449.                     } else setbrush(DYNAMITE);
  450.                 break;
  451.                 case F5:
  452.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  453.                     {   fillfield(WOOD);
  454.                     } else setbrush(WOOD);
  455.                 break;
  456.                 case F6:
  457.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  458.                     {   fillfield(STONE);
  459.                     } else setbrush(STONE);
  460.                 break;
  461.                 case F7:
  462.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  463.                     {   fillfield(METAL);
  464.                     } else setbrush(METAL);
  465.                 break;
  466.                 case NUMERICZERO:
  467.                     if (!(qual & IEQUALIFIER_REPEAT))
  468.                     {   if (!sticky)
  469.                         {   sticky = TRUE;
  470.                             say("Sticky mode on", WHITE);
  471.                             stamp(brush);
  472.                         } else
  473.                         {   sticky = FALSE;
  474.                             say("Sticky mode off", WHITE);
  475.                             dot();
  476.                     }   }
  477.                 break;
  478.                 case NUMERICDOT:
  479.                     stamp(brush);
  480.                 break;
  481.                 case KEY_X:
  482.                     undot();
  483.                     fex = FIELDX - fex;
  484.                     dot();
  485.                 break;
  486.                 case KEY_Y:
  487.                     undot();
  488.                     fey = FIELDY - fey;
  489.                     dot();
  490.                 break;
  491.                 case NUMERICFOUR:
  492.                 case LEFT:
  493.                     undot();
  494.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
  495.                     {   fex = 0;
  496.                     } elif ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
  497.                     {   fex = xwrap(fex - ALTJUMP);
  498.                     } else
  499.                     {   fex = xwrap(fex - 1);
  500.                     }
  501.                     if (sticky)
  502.                     {   stamp(brush);
  503.                     } else
  504.                     {   dot();
  505.                     }
  506.                 break;
  507.                 case NUMERICSIX:
  508.                 case RIGHT:
  509.                     undot();
  510.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
  511.                     {   fex = FIELDX;
  512.                     } elif ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
  513.                     {   fex = xwrap(fex + ALTJUMP);
  514.                     } else
  515.                     {   fex = xwrap(fex + 1);
  516.                     }
  517.                     if (sticky)
  518.                     {   stamp(brush);
  519.                     } else
  520.                     {   dot();
  521.                     }
  522.                 break;
  523.                 case NUMERICEIGHT:
  524.                 case UP:
  525.                     undot();
  526.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
  527.                     {   fey = 0;
  528.                     } elif ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
  529.                     {   fey = ywrap(fey - ALTJUMP);
  530.                     } else
  531.                     {   fey = ywrap(fey - 1);
  532.                     }
  533.                     if (sticky)
  534.                     {   stamp(brush);
  535.                     } else
  536.                     {   dot();
  537.                     }
  538.                 break;
  539.                 case NUMERICFIVE:
  540.                 case NUMERICTWO:
  541.                 case DOWN:
  542.                     undot();
  543.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
  544.                     {   fey = FIELDY;
  545.                     } elif ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
  546.                     {   fey = ywrap(fey + ALTJUMP);
  547.                     } else
  548.                     {   fey = ywrap(fey + 1);
  549.                     }
  550.                     if (sticky)
  551.                     {   stamp(brush);
  552.                     } else
  553.                     {   dot();
  554.                     }
  555.                 break;
  556.                 case NUMERICSEVEN:
  557.                     undot();
  558.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
  559.                     {   fex = 0;
  560.                         fey = 0;
  561.                     } elif ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
  562.                     {   fex = xwrap(fex - ALTJUMP);
  563.                         fey = ywrap(fey - ALTJUMP);
  564.                     } else
  565.                     {   fex = xwrap(fex - 1);
  566.                         fey = ywrap(fey - 1);
  567.                     }
  568.                     if (sticky)
  569.                     {   stamp(brush);
  570.                     } else
  571.                     {   dot();
  572.                     }
  573.                 break;
  574.                 case NUMERICNINE:
  575.                     undot();
  576.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
  577.                     {   fex = FIELDX;
  578.                         fey = 0;
  579.                     } elif ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
  580.                     {   fex = xwrap(fex + ALTJUMP);
  581.                         fey = ywrap(fey - ALTJUMP);
  582.                     } else
  583.                     {   fex = xwrap(fex + 1);
  584.                         fey = ywrap(fey - 1);
  585.                     }
  586.                     if (sticky)
  587.                     {   stamp(brush);
  588.                     } else
  589.                     {   dot();
  590.                     }
  591.                 break;
  592.                 case NUMERICONE:
  593.                     undot();
  594.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
  595.                     {   fex = 0;
  596.                         fey = FIELDY;
  597.                     } elif ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
  598.                     {   fex = xwrap(fex - ALTJUMP);
  599.                         fey = ywrap(fey + ALTJUMP);
  600.                     } else
  601.                     {   fex = xwrap(fex - 1);
  602.                         fey = ywrap(fey + 1);
  603.                     }
  604.                     if (sticky)
  605.                     {   stamp(brush);
  606.                     } else
  607.                     {   dot();
  608.                     }
  609.                 break;
  610.                 case NUMERICTHREE:
  611.                     undot();
  612.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
  613.                     {   fex = FIELDX;
  614.                         fey = FIELDY;
  615.                     } elif ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
  616.                     {   fex = xwrap(fex + ALTJUMP);
  617.                         fey = ywrap(fey + ALTJUMP);
  618.                     } else
  619.                     {   fex = xwrap(fex + 1);
  620.                         fey = ywrap(fey + 1);
  621.                     }
  622.                     if (sticky)
  623.                     {   stamp(brush);
  624.                     } else
  625.                     {   dot();
  626.                     }
  627.                 break;
  628.                 default:
  629.                 break;
  630.                 } // hctiws
  631.             break;
  632.             case IDCMP_MOUSEBUTTONS:
  633.                 undot();
  634.                 if (code == SELECTUP)
  635.                 {   leftdown = FALSE;
  636.                 } elif (code == SELECTDOWN)
  637.                 {   leftdown = TRUE;
  638.                 } elif (code == MENUUP)
  639.                 {   rightdown = FALSE;
  640.                 } /* MENUDOWN is handled earlier */
  641.             break;
  642.             case IDCMP_CLOSEWINDOW:
  643.                 cleanexit(EXIT_SUCCESS);
  644.             break;
  645.             case IDCMP_REFRESHWINDOW:
  646.                 GT_BeginRefresh(MainWindowPtr);
  647.                 GT_EndRefresh(MainWindowPtr, TRUE);
  648.             break;
  649.             default:
  650.                 /* IDCMP_MENUVERIFY, IDCMP_INTUITICKS, IDCMP_ACTIVEWINDOW */
  651.             break;
  652.         }   }
  653.  
  654.         if (joy)
  655.         {   if (GetMsg(JoyPortPtr))
  656.             {   if (GameEvent.ie_Code == IECODE_LBUTTON || GameEvent.ie_Qualifier == IEQUALIFIER_LEFTBUTTON)
  657.                 {   stamp(brush);
  658.                 }
  659.                 deltax = (SBYTE) GameEvent.ie_position.ie_xy.ie_x;
  660.                 deltay = (SBYTE) GameEvent.ie_position.ie_xy.ie_y;
  661.                 sendreadrequest();
  662.             }
  663.             if (deltax || deltay)
  664.             {   if (!timer)
  665.                 {   TimerRqPtr->tr_node.io_Command = TR_ADDREQUEST;
  666.                     TimerRqPtr->tr_time.tv_secs    = 0;
  667.                     TimerRqPtr->tr_time.tv_micro   = JOYDELAY;
  668.                     SendIO((struct IORequest *) TimerRqPtr);
  669.                     timer = TRUE;
  670.                 } elif (CheckIO((struct IORequest *) TimerRqPtr))
  671.                 // CheckIO() returns NULL if complete, pointer if incomplete.
  672.                 {   undot();
  673.                     fex = xwrap(fex + deltax);
  674.                     fey = ywrap(fey + deltay);
  675.                     dot();
  676.                     timer = FALSE;
  677.         }   }   }
  678.  
  679.         if (leftdown || rightdown)
  680.         {   pointerx = xpixeltosquare(MainWindowPtr->MouseX);
  681.             pointery = ypixeltosquare(MainWindowPtr->MouseY);
  682.             if (valid(pointerx, pointery))
  683.             {   undot();
  684.                 fex = pointerx;
  685.                 fey = pointery;
  686.                 if (leftdown)
  687.                 {   stamp(brush);
  688.                 } else
  689.                 {   // assert(rightdown);
  690.                     stamp(EMPTY);
  691.         }   }   }
  692.         elif
  693.         (   leftdown && pointerx == GADGETX &&
  694.             (   pointery == EMPTYGADGET
  695.              || pointery == SILVERGADGET
  696.              || pointery == GOLDGADGET
  697.              || pointery == DYNAMITEGADGET
  698.              || pointery == WOODGADGET
  699.              || pointery == STONEGADGET
  700.              || pointery == METALGADGET
  701.         )   )
  702.     {   switch (pointery)
  703.         {
  704.         case GOLDGADGET:
  705.             setbrush(GOLD);
  706.         break;
  707.             case SILVERGADGET:
  708.                 setbrush(SILVER);
  709.             break;
  710.         case EMPTYGADGET:
  711.             setbrush(EMPTY);
  712.         break;
  713.         case WOODGADGET:
  714.             setbrush(WOOD);
  715.             break;
  716.             case DYNAMITEGADGET:
  717.                 setbrush(DYNAMITE);
  718.             break;
  719.         break;
  720.         case STONEGADGET:
  721.             setbrush(STONE);
  722.         break;
  723.         case METALGADGET:
  724.             setbrush(METAL);
  725.         break;
  726.             default:
  727.             break;
  728.     }   }   }
  729.  
  730.     /* exit to title screen */
  731.  
  732.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_EDIT, NOITEM, NOSUB));
  733.     if (timer)
  734.     {   AbortIO((struct IORequest *) TimerRqPtr);
  735.          WaitIO((struct IORequest *) TimerRqPtr);
  736.     }
  737.     setpointer(NORMAL);
  738.     if (clearthem)
  739.         clearhiscores();
  740.     matchteleports();
  741. }
  742.  
  743. MODULE void stamp(UBYTE square)
  744. {   if (square == START)
  745.     {   draw(startx[level], starty[level], EMPTY);
  746.         board[level][startx[level]][starty[level]] = EMPTY;
  747.         startx[level] = fex;
  748.         starty[level] = fey;
  749.         board[level][fex][fey] = EMPTY;
  750.     } else
  751.     {   board[level][fex][fey] = square;
  752.     }
  753.  
  754.     draw(fex, fey, square);
  755.     dot();
  756.     modified = clearthem = TRUE;
  757. }
  758.  
  759. MODULE void undot(void)
  760. {   if (startx[level] == fex && starty[level] == fey)
  761.         draw(fex, fey, START);
  762.     else draw(fex, fey, board[level][fex][fey]);
  763. }
  764.  
  765. MODULE void fillfield(UBYTE which)
  766. {   SBYTE x, y;
  767.  
  768.     // Service routine for field editor.
  769.  
  770.     for (x = 0; x <= FIELDX; x++)
  771.     {   for (y = 0; y <= FIELDY; y++)
  772.         {   board[level][x][y] = which;
  773.             draw(x, y, which);
  774.     }   }
  775.     board[level][startx[level]][starty[level]] = EMPTY;
  776.     draw(startx[level], starty[level], START);
  777.     dot();
  778. }
  779.  
  780. AGLOBAL void setbrush(UBYTE newbrush)
  781. {   brush = newbrush;
  782.     setpointer(brush);
  783.     underline(brush);
  784. }
  785.  
  786. MODULE void underline(UBYTE square)
  787. {   /* Removes old underline, draws new underline.
  788.  
  789.     square: which square-type to underline, or 255 for clear only.
  790.     Squares which do not correspond to any pseudo-gadgets
  791.     (eg. objects) are converted to 255s. */
  792.  
  793.     PERSIST SWORD oldy = 255;
  794.     AUTO    SWORD y;
  795.  
  796.         switch(square)
  797.     {
  798.     case EMPTY:
  799.             y = UNDERLINEOFFSET;
  800.     break;
  801.         case SILVER:
  802.         y = UNDERLINEOFFSET + (SQUAREY *  3);
  803.     break;
  804.     case GOLD:
  805.             y = UNDERLINEOFFSET + (SQUAREY *  6);
  806.     break;
  807.         case DYNAMITE:
  808.             y = UNDERLINEOFFSET + (SQUAREY *  9);
  809.         break;
  810.     case WOOD:
  811.             y = UNDERLINEOFFSET + (SQUAREY * 12);
  812.     break;
  813.     case STONE:
  814.             y = UNDERLINEOFFSET + (SQUAREY * 15);
  815.     break;
  816.     case METAL:
  817.             y = UNDERLINEOFFSET + (SQUAREY * 18);
  818.     break;
  819.     default:
  820.         square = 255;
  821.             y = 0; // to avoid spurious warnings
  822.         break;
  823.     }
  824.  
  825.     if (oldy != 255)
  826.     {   SetAPen(MainWindowPtr->RPort, BLACK);
  827.         Move(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, oldy);
  828.         Draw(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, oldy + SQUAREY + 3);
  829.     }
  830.     if (square != 255)
  831.     {   SetAPen(MainWindowPtr->RPort, WHITE);
  832.         Move(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, y);
  833.         Draw(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, y + SQUAREY + 3);
  834.         oldy = y;
  835. }    }
  836.  
  837. MODULE void dot(void)
  838. {    SWORD xx, yy;
  839.  
  840.     /* Squares are dotted as follows:
  841.     
  842.      012345678
  843.     0.........
  844.     1.........
  845.     2...WWW...
  846.     3...WWWB..
  847.     4....BBB..
  848.     5......... */
  849.  
  850.     xx = (fex * SQUAREX) + STARTXPIXEL;
  851.     yy = (fey * SQUAREY) + STARTYPIXEL;
  852.  
  853.     if (sticky)
  854.         SetAPen(MainWindowPtr->RPort, RED);
  855.     else SetAPen(MainWindowPtr->RPort, WHITE);
  856.     WritePixel(MainWindowPtr->RPort, xx + 3, yy + 2);
  857.     WritePixel(MainWindowPtr->RPort, xx + 4, yy + 2);
  858.     WritePixel(MainWindowPtr->RPort, xx + 5, yy + 2);
  859.     WritePixel(MainWindowPtr->RPort, xx + 3, yy + 3);
  860.     WritePixel(MainWindowPtr->RPort, xx + 4, yy + 3);
  861.     WritePixel(MainWindowPtr->RPort, xx + 5, yy + 3);
  862.     SetAPen(MainWindowPtr->RPort, BLACK);
  863.     WritePixel(MainWindowPtr->RPort, xx + 6, yy + 3);
  864.     WritePixel(MainWindowPtr->RPort, xx + 4, yy + 4);
  865.     WritePixel(MainWindowPtr->RPort, xx + 5, yy + 4);
  866.     WritePixel(MainWindowPtr->RPort, xx + 6, yy + 4);
  867. }
  868.  
  869. MODULE void setpointer(UBYTE pointer) {
  870. switch (pointer) {
  871. case GOLD:
  872.         SetRGB4(&ScreenPtr->ViewPort, 17, 10, 10,  2);          /* fill */
  873.     SetRGB4(&ScreenPtr->ViewPort, 18,  8,  4,  2);        /* shadow */
  874.     SetRGB4(&ScreenPtr->ViewPort, 19, 12, 12,  2);        /* shine */
  875.         SetPointer(MainWindowPtr, CustomPointer, 6, 5, -3, -2);
  876.     break;
  877. case SILVER:
  878.         SetRGB4(&ScreenPtr->ViewPort, 17, 11, 11, 11);          /* fill */
  879.     SetRGB4(&ScreenPtr->ViewPort, 18,  6,  6,  6);        /* shadow */
  880.     SetRGB4(&ScreenPtr->ViewPort, 19, 15, 15, 15);        /* shine */
  881.         SetPointer(MainWindowPtr, CustomPointer, 6, 5, -3, -2);
  882.     break;
  883. case EMPTY:
  884.         SetRGB4(&ScreenPtr->ViewPort, 17,  5,  5,  5);          /* fill */
  885.     SetRGB4(&ScreenPtr->ViewPort, 18,  0,  0,  0);        /* shadow */
  886.         SetRGB4(&ScreenPtr->ViewPort, 19,  9,  9,  9);          /* shine */
  887.         SetPointer(MainWindowPtr, CustomPointer, 6, 5, -3, -2);
  888.     break;
  889. case WOOD:
  890.     SetRGB4(&ScreenPtr->ViewPort, 17,  8,  4,  2);        /* fill */
  891.         SetRGB4(&ScreenPtr->ViewPort, 18,  5,  5,  5);          /* shadow */
  892.         SetRGB4(&ScreenPtr->ViewPort, 19, 10, 10,  2);          /* shine */
  893.         SetPointer(MainWindowPtr, CustomPointer, 6, 5, -3, -2);
  894.     break;
  895. case STONE:
  896.     SetRGB4(&ScreenPtr->ViewPort, 17,  0,  0,  0);        /* fill */
  897.         SetRGB4(&ScreenPtr->ViewPort, 18,  5,  5,  5);          /* shadow */
  898.         SetRGB4(&ScreenPtr->ViewPort, 19,  9,  9,  9);          /* shine */
  899.         SetPointer(MainWindowPtr, CustomPointer, 6, 5, -3, -2);
  900.     break;
  901. case METAL:
  902.     SetRGB4(&ScreenPtr->ViewPort, 17,  6,  6, 15);        /* fill */
  903.     SetRGB4(&ScreenPtr->ViewPort, 18,  3,  3, 15);        /* shadow */
  904.         SetRGB4(&ScreenPtr->ViewPort, 19, 11, 11, 11);          /* shine */
  905.         SetPointer(MainWindowPtr, CustomPointer, 6, 5, -3, -2);
  906.     break;
  907. default:
  908.     SetRGB4(&ScreenPtr->ViewPort, 17, 14,  4,  4);        /* fill */
  909.     SetRGB4(&ScreenPtr->ViewPort, 18,  3,  3,  3);        /* shadow */
  910.     SetRGB4(&ScreenPtr->ViewPort, 19, 12, 12, 12);        /* shine */
  911.     ClearPointer(MainWindowPtr);
  912.     break;
  913. }   }
  914.  
  915. MODULE SWORD xpixeltosquare(SWORD x)
  916. {    x = (x - STARTXPIXEL) / SQUAREX;
  917.     if (x < 0)
  918.         x--;
  919.     return (x);
  920. }
  921. MODULE SWORD ypixeltosquare(SWORD y)
  922. {    y = (y - STARTYPIXEL) / SQUAREY;
  923.     if (y < 0)
  924.         y--;
  925.     return (y);
  926. }
  927.